package com.chuangjiangx.member.basic.web.redis;

import com.chuangjiangx.commons.JacksonUtils;
import com.chuangjiangx.member.basic.ddd.query.MemberQuery;
import com.chuangjiangx.member.basic.ddd.domain.model.MbrUserContext;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.concurrent.TimeUnit;

/**
 * @author cj-ch
 * @date 2018/2/11 下午5:07
 */
@Slf4j
@Service
public class SessionService {

    public static final String USER_KEY = "USER_KEY";
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private MemberQuery memberQuery;
    @Autowired
    private ObjectMapper objectMapper;

    /**
     *
     * @param context
     * @return
     */
    public void saveUserContext(MbrUserContext context) {
        HttpServletRequest request = getRequest();
        if(isAppletReferer(request)){
            // 这个openid是会员小程序的openid
            String openid =  StringUtils.defaultIfBlank(request.getHeader("openid"),request.getParameter("openid"));
            if (StringUtils.isNotEmpty(openid) && !"undefined".equals(openid)){
                redisTemplate.opsForValue()
                        .set(openid,JacksonUtils.toJson(objectMapper,context),
                                1,TimeUnit.HOURS);
            }else{
                log.warn("小程序内访问,没有获取到openid! {}",openid);
            }
        } else {
            HttpSession session = getSession();
            session.setAttribute(USER_KEY,context);
        }
    }


    public MbrUserContext updateUserContext(MbrUserContext context) {
        saveUserContext(context);
        return context;
    }

    /**
     * 是否会员小程序内访问
     * @param request
     * @return
     */
    public boolean isAppletReferer(HttpServletRequest request){
        // 会员小程序访问标识
        String mbr_applet = request.getHeader("mbr-applet");
        if("1".equals(mbr_applet)){
            // "1" - 代表会员小程序访问标识
            return true;
        }
        return false;
    }

    public MbrUserContext currentUserContext(){
        MbrUserContext userContext = null;
        HttpServletRequest request = getRequest();
        if(isAppletReferer(request)){
            // 这个openid是会员小程序的openid
            String openid =  StringUtils.defaultIfBlank(request.getHeader("openid"),request.getParameter("openid"));
            if (StringUtils.isNotEmpty(openid) && !"undefined".equals(openid)){
                String json = redisTemplate.opsForValue().get(openid);
                if(StringUtils.isNotBlank(json)){
                    userContext = JacksonUtils.toObject(objectMapper,json,MbrUserContext.class);
                }
            }else{
                log.warn("小程序内访问,没有获取到openid! {}",openid);
            }
        }else{
            userContext =  (MbrUserContext) getSession().getAttribute(USER_KEY);
        }

        if(null == userContext){
            userContext = MbrUserContext.builder().build();
        }
        return userContext;
    }


    public void loginOut() {
        HttpServletRequest request = getRequest();
        if(isAppletReferer(request)){
            // 这个openid是会员小程序的openid
            String openid =  StringUtils.defaultIfBlank(request.getHeader("openid"),request.getParameter("openid"));
            if (StringUtils.isNotEmpty(openid) && !"undefined".equals(openid)){
                redisTemplate.delete(openid);
            }
        }else{
            request.getSession().removeAttribute(USER_KEY);
        }
    }

    public MbrUserContext cleanUser(Long merchantId){
        MbrUserContext userContext = MbrUserContext.builder()
                .merchantId(merchantId).build();
        saveUserContext(userContext);
        return userContext;
    }

    private HttpSession getSession(){
        return  ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest().getSession();
    }

    private HttpServletRequest getRequest(){
        return  ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
    }
}
